//set event handlers for different events

//DEPENDS ON EVENT_HANDLER
//DEPENDS ON EVENT_NORMALIZER
//DEPENDS ON EVENT_STACK

/*
	'l'	=> left click
	'c'	=> center/middle click
	'r'	=> right click
	'd'	=> drag
	'm'	=> mouse move
	'u' => mouse up
	's' => document scroll
	'o' => non-document (overflow) scroll
*/

(function (that) {

	if(!that){throw "Global object missing, bitchesss";}


	var that 						= that						//local Link to Global-Object or throw Exception
	,	mousedown_max_duration 		= 250						// Minimum time that needs to pass before a mouse up event is tracked
	,	mousedown 					= 0							// Mousedown is set to 1 on mouse down and increased on mousemove to distinguish drag from click
	,	mousedown_time 				= 0							// The time when the mouse was pushed down to determine duration
	,	last_scroll_left 			= document.body.scrollLeft	// Determine if event is document or overflow scroll by comparing scroll position
	,	last_scroll_top 			= document.body.scrollTop
	,	scroll_event_type 			= 'mousewheel';


	// Special event for IE
	try {
		MouseScrollEvent;
		scroll_event_type = 'DOMMouseScroll';
	} catch (e) {};





	/*
	* Helper function to determine if the duration necessary for a drag event ellapsed
	*
	*@return 	Void
	*/
	var is_drag = function () {
		return new Date().getTime() - mousedown_max_duration > mousedown_time;
	};



	/*
	* The handler that is attached to any mouse scrolling
	*
	* The last scroll position of the document body is stored and used
	* to determine if the entire document was scrolled ('s') or just an
	* overflowing element on the üage ('o')
	*
	* @param	e	The event object
	* @return 		Void
	*/
	var scroll_handler = function (e) {

		var new_scroll_left 	= document.body.scrollLeft
		,	new_scroll_top 		= document.body.scrollTop;

		if (new_scroll_left != last_scroll_left || new_scroll_top != last_scroll_top) {
			that.event_stack('s', new_scroll_left, last_scroll_top);
			last_scroll_left = new_scroll_left;
			last_scroll_top = new_scroll_top;
		} else {
			// Good idea to use mouse position at scroll for overflow scroll events?
			that.event_stack('o', e.normalized_x, e.pageY);
		}
	};



	/*
	* The handler that is attached to any mouse movement
	*
	* Unless the mouse is down, an 'm' event with mouse coordinates is tracked
	* In case the mouse button is down, a 'd' (drag) event is tracked if the minimum
	* amount of time for a drag event has passed.
	*
	* @param	e	The event object
	* @return 		Void
	*/
	var move_handler = function(e){

		if (mousedown) {
			if (is_drag()) {
				that.event_stack('d', e.normalized_x, e.pageY);
				mousedown++;
			}
		} else {
			that.event_stack('m', e.normalized_x, e.pageY);
		}
	};



	/*
	* The handler that is attached to mouse down event
	*
	* This is used to track actual clicks and depending on which button
	* is pressed, a different event is tracked with the mouse coordinates
	* Furthermore the mousedown state and time are stored to later determine
	* if a mouse up event requires an 'u' event
	*
	* @param e		The event object
	* @return 		Void
	*/
	var down_handler = function (e) {

		mousedown = 1;
		mousedown_time = new Date().getTime();

		if (e.which === 1) {
			that.event_stack('l', e.normalized_x, e.pageY);
		} else if (e.which === 2) {
			that.event_stack('c', e.normalized_x, e.pageY);
		} else if (e.which === 3) {
			that.event_stack('r', e.normalized_x, e.pageY);
		}
	};



	/*
	* The handler that is attached to mouse up event
	*
	* This handler is used to possible track an up ('u') event when the
	* mouse button is released. This only happens if the mouse was dragged
	* or the necessary time has ellapsed.
	*
	* @param e		The event object
	* @return 		Void
	*/
	var up_handler = function (e) {

		if (mousedown > 1 || is_drag()) {
			that.event_stack('u', e.normalized_x, e.pageY);
		}

		mousedown = 0;
		mousedown_start = 0;
	};



	that.event_handler(scroll_handler,{event_type: scroll_event_type, timer: 100});
	that.event_handler(move_handler,{event_type: 'mousemove', timer: 100});
	that.event_handler(down_handler,{event_type: 'mousedown'});
	that.event_handler(up_handler,{event_type: 'mouseup'});
	that.event_handler(that.event_stack_flush, {event_type: 'unload'}, window);	//flush data to server on unload
	that.event_handler(that.calc_browser_sizes, {event_type: 'resize'}, window);	//recalculate available space and top-offset in browser everytime a resize happens
	that.event_handler(that.calc_browser_sizes, {event_type: scroll_event_type}, window);	//recalculate available space and top-offset in browser everytime a scroll happens
})(sauberfant);
